package etilan.Client.Connectors;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.UUID;

import etilan.Client.MainActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.os.Message;
import android.util.Log;

public class bluetoothConn implements Conn{
    // Debugging
    private static final String TAG = "BluetoothChatService";
    private static final boolean D = false;
    // Unique UUID for this application
    private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
    // Member fields
    private int mState;
    private MainActivity ap;
    private  BluetoothAdapter mAdapter;
    private  BluetoothSocket mmSocket;
    private  InputStream mmInStream;
    private  InputStreamReader mmInStreamr;
    private  OutputStream mmOutStream;
    private  BluetoothDevice mmDevice;
    private boolean stopping = false;
    
    // Constants that indicate the current connection state
    public static final int STATE_NONE = 0;       // we're doing nothing
    public static final int STATE_CONNECTING = 1; // now initiating an outgoing connection
    public static final int STATE_CONNECTED = 2;  // now connected to a remote device

    public bluetoothConn(String deviceAddress) {
        mAdapter = BluetoothAdapter.getDefaultAdapter();
        mmDevice=mAdapter.getRemoteDevice(deviceAddress);
        mState = STATE_NONE;
    }

    private void setState(int state) {
        if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
        mState = state;
    }

    public int getState() {
        return mState;
    }
    
    public void setDevice(String deviceAddress){
    	mmDevice=mAdapter.getRemoteDevice(deviceAddress);
    }

    public void connInit() throws IOException {
    	if(stopping) return; // Escape method
        if (D) Log.d(TAG, "connect to: " + mmDevice);
        // Start the thread to connect with the given device
        setState(STATE_CONNECTING); 
    	mmSocket = mmDevice.createRfcommSocketToServiceRecord(MY_UUID);
         
     // Always cancel discovery because it will slow down a connection
        mAdapter.cancelDiscovery();

        // Make a connection to the BluetoothSocket
        try {
            // This is a blocking call and will only return on a
            // successful connection or an exception
            mmSocket.connect();
        } catch (IOException e) { 
        	mState = STATE_NONE;
            try {
                mmSocket.close();
            } 
            catch (IOException e2) {Log.e(TAG, "unable to close() socket during connection failure", e2);}
            return;
        }
        if(!stopping){
	        // Get the BluetoothSocket input and output streams
	      //  try {
	        	mmInStream = mmSocket.getInputStream();
	        	mmOutStream = mmSocket.getOutputStream();
	        	mmInStreamr=new InputStreamReader(mmInStream);
	        	setState(STATE_CONNECTED);
	        	setConnectedStatus(true,  mmDevice.getAddress());
	        //} 
	        //catch (IOException e) {Log.e(TAG, "temp sockets not created", e);}
        }
    }

    public void write(byte[] data) throws IOException {
    	if (!stopping){
	         mmOutStream.write(data);
	         mmOutStream.flush();
    	}
    }

    public char[] read() throws IOException{
    	if (mmInStreamr.ready() && !stopping){
	    	 char[] buffer = new char[1024];
	    	 mmInStreamr.read(buffer);
	    	 String st=new String(buffer);
	    	if(st.startsWith("<STOP>")){
	    		connectionLost();
	    		setConnectedStatus(false,"");
	    	}
	    	return buffer;
    	}
    	return null;
    }
    
    private void connectionLost() {
        setState(STATE_NONE);
    }

    public void kill() {
        try {
        	if(!stopping)
    		{
        		setState(STATE_NONE);
    			stopping = true;
    			mmSocket.close();
    		}
        } 
        catch (IOException e) {Log.e(TAG, "close() of connect socket failed", e);}
    }
    
    public final synchronized void changeParentWindow(MainActivity a){
		ap = a;
		if(ap != null)
			if(mmSocket != null)
				if(mState==STATE_CONNECTED)
					setConnectedStatus(true, mmDevice.getAddress());
	}
	
	private void setConnectedStatus(boolean activated,String ip){
		Message msg = new Message();
		Bundle b = new Bundle();
		b.putString("ip", ip);
		msg.arg1 = activated ? 1 : 0;
		msg.setData(b);
		ap.isConnectedCallback.sendMessage(msg);
	}

	public boolean socketOn() {
		return (mState==STATE_CONNECTED);
	}
	
	public boolean isStopping(){
		return stopping;
	}
}